package com.irain.pp.tool.redis.monitor;

import com.irain.pp.tool.api.monitor.MethodInfo;
import com.irain.pp.tool.api.monitor.MethodMonitorSupport;
import com.irain.pp.tool.redis.spring.PpRedisTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author iRain
 * @date 2017/12/20 14:07
 */
@Component
public class RedisMethodMonitor implements MethodMonitorSupport {

    @Autowired
    PpRedisTemplate ppRedisTemplate;

    private static final String PREFIX = "MONITOR:METHOD:";
    private static final String TOTAL_METHODS_SET_KEY = PREFIX +  "TOTAL_LIST:";

    @Override
    public List<MethodInfo> getMethodInfo(long start, long end){
        Set<ZSetOperations.TypedTuple<Object>> zSet = ppRedisTemplate.opsForZSet().rangeWithScores(TOTAL_METHODS_SET_KEY, start, end);
        List<MethodInfo> methodInfoList = new ArrayList<>((int)(end - start + 1));
        zSet.forEach(tuple ->{
            MethodInfo methodInfo = new MethodInfo();
            methodInfo.setMethodName((String)tuple.getValue());
            methodInfo.setLastRunTime(new Date(tuple.getScore().longValue()));
            Long runTimes = (Long)ppRedisTemplate.opsForValue().get(genKey(methodInfo.getMethodName()));
            methodInfo.setRunTimes (runTimes == null ? 0L : runTimes);
            methodInfoList.add(methodInfo);
        });
        return methodInfoList;
    }

    @Override
    public void updateMethodInfo(Method method){
        String methodName = method.getName();
        ppRedisTemplate.opsForZSet().add(TOTAL_METHODS_SET_KEY,methodName,System.currentTimeMillis());
        ppRedisTemplate.opsForValue().increment(genKey(methodName),1);
    }

    private String genKey(String methodName){
        return PREFIX + methodName + ":";
    }

}
